home *** CD-ROM | disk | FTP | other *** search
/ Young Minds / Young Minds Interactive CD-ROM.ISO / rogue / spec_hit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-05-13  |  9.7 KB  |  501 lines

  1. /*
  2.  * special_hit.c
  3.  *
  4.  * This source herein may be modified and/or distributed by anybody who
  5.  * so desires, with the following restrictions:
  6.  *    1.)  No portion of this notice shall be removed.
  7.  *    2.)  Credit shall not be taken for the creation of this source.
  8.  *    3.)  This code is not to be traded, sold, or used for personal
  9.  *         gain or profit.
  10.  *
  11.  */
  12.  
  13. #ifndef CURSES
  14. #include <curses.h>
  15. #endif CURSES
  16. #include "rogue.h"
  17.  
  18. short less_hp = 0;
  19. char *flame_name = "flame";
  20. boolean being_held;
  21.  
  22. extern short cur_level, max_level, blind, levitate, ring_exp;
  23. extern long level_points[];
  24. extern boolean detect_monster, mon_disappeared;
  25. extern boolean sustain_strength, maintain_armor;
  26. extern char *you_can_move_again;
  27.  
  28. special_hit(monster)
  29. object *monster;
  30. {
  31.     if ((monster->m_flags & CONFUSED) && rand_percent(66)) {
  32.         return;
  33.     }
  34.     if (monster->m_flags & RUSTS) {
  35.         rust(monster);
  36.     }
  37.     if ((monster->m_flags & HOLDS) && !levitate) {
  38.         being_held = 1;
  39.     }
  40.     if (monster->m_flags & FREEZES) {
  41.         freeze(monster);
  42.     }
  43.     if (monster->m_flags & STINGS) {
  44.         sting(monster);
  45.     }
  46.     if (monster->m_flags & DRAINS_LIFE) {
  47.         drain_life();
  48.     }
  49.     if (monster->m_flags & DROPS_LEVEL) {
  50.         drop_level();
  51.     }
  52.     if (monster->m_flags & STEALS_GOLD) {
  53.         steal_gold(monster);
  54.     } else if (monster->m_flags & STEALS_ITEM) {
  55.         steal_item(monster);
  56.     }
  57. }
  58.  
  59. rust(monster)
  60. object *monster;
  61. {
  62.     if ((!rogue.armor) || (get_armor_class(rogue.armor) <= 1) ||
  63.         (rogue.armor->which_kind == LEATHER)) {
  64.         return;
  65.     }
  66.     if ((rogue.armor->is_protected) || maintain_armor) {
  67.         if (monster && (!(monster->m_flags & RUST_VANISHED))) {
  68.             message("the rust vanishes instantly", 0);
  69.             monster->m_flags |= RUST_VANISHED;
  70.         }
  71.     } else {
  72.         rogue.armor->d_enchant--;
  73.         message("your armor weakens", 0);
  74.         print_stats(STAT_ARMOR);
  75.     }
  76. }
  77.  
  78. freeze(monster)
  79. object *monster;
  80. {
  81.     short freeze_percent = 99;
  82.     short i, n;
  83.  
  84.     if (rand_percent(12)) {
  85.         return;
  86.     }
  87.     freeze_percent -= (rogue.str_current+(rogue.str_current / 2));
  88.     freeze_percent -= ((rogue.exp + ring_exp) * 4);
  89.     freeze_percent -= (get_armor_class(rogue.armor) * 5);
  90.     freeze_percent -= (rogue.hp_max / 3);
  91.  
  92.     if (freeze_percent > 10) {
  93.         monster->m_flags |= FREEZING_ROGUE;
  94.         message("you are frozen", 1);
  95.  
  96.         n = get_rand(4, 8);
  97.         for (i = 0; i < n; i++) {
  98.             mv_mons();
  99.         }
  100.         if (rand_percent(freeze_percent)) {
  101.             for (i = 0; i < 50; i++) {
  102.                 mv_mons();
  103.             }
  104.             killed_by((object *)0, HYPOTHERMIA);
  105.         }
  106.         message(you_can_move_again, 1);
  107.         monster->m_flags &= (~FREEZING_ROGUE);
  108.     }
  109. }
  110.  
  111. steal_gold(monster)
  112. object *monster;
  113. {
  114.     int amount;
  115.  
  116.     if ((rogue.gold <= 0) || rand_percent(10)) {
  117.         return;
  118.     }
  119.  
  120.     amount = get_rand((cur_level * 10), (cur_level * 30));
  121.  
  122.     if (amount > rogue.gold) {
  123.         amount = rogue.gold;
  124.     }
  125.     rogue.gold -= amount;
  126.     message("your purse feels lighter", 0);
  127.     print_stats(STAT_GOLD);
  128.     disappear(monster);
  129. }
  130.  
  131. steal_item(monster)
  132. object *monster;
  133. {
  134.     object *obj;
  135.     short i, n, t;
  136.     char desc[80];
  137.     boolean has_something = 0;
  138.  
  139.     if (rand_percent(15)) {
  140.         return;
  141.     }
  142.     obj = rogue.pack.next_object;
  143.  
  144.     if (!obj) {
  145.         goto DSPR;
  146.     }
  147.     while (obj) {
  148.         if (!(obj->in_use_flags & BEING_USED)) {
  149.             has_something = 1;
  150.             break;
  151.         }
  152.         obj = obj->next_object;
  153.     }
  154.     if (!has_something) {
  155.         goto DSPR;
  156.     }
  157.     n = get_rand(0, MAX_PACK_COUNT);
  158.     obj = rogue.pack.next_object;
  159.  
  160.     for (i = 0; i <= n; i++) {
  161.         obj = obj->next_object;
  162.         while ((!obj) || (obj->in_use_flags & BEING_USED)) {
  163.             if (!obj) {
  164.                 obj = rogue.pack.next_object;
  165.             } else {
  166.                 obj = obj->next_object;
  167.             }
  168.         }
  169.     }
  170.     (void) strcpy(desc, "she stole ");
  171.     if (obj->what_is != WEAPON) {
  172.         t = obj->quantity;
  173.         obj->quantity = 1;
  174.     }
  175.     get_desc(obj, desc+10);
  176.     message(desc, 0);
  177.  
  178.     obj->quantity = ((obj->what_is != WEAPON) ? t : 1);
  179.  
  180.     vanish(obj, 0, &rogue.pack);
  181. DSPR:
  182.     disappear(monster);
  183. }
  184.  
  185. disappear(monster)
  186. object *monster;
  187. {
  188.     short row, col;
  189.  
  190.     row = monster->row;
  191.     col = monster->col;
  192.  
  193.     dungeon[row][col] &= ~MONSTER;
  194.     if (rogue_can_see(row, col)) {
  195.         mvaddch(row, col, get_dungeon_char(row, col));
  196.     }
  197.     take_from_pack(monster, &level_monsters);
  198.     free_object(monster);
  199.     mon_disappeared = 1;
  200. }
  201.  
  202. cough_up(monster)
  203. object *monster;
  204. {
  205.     object *obj;
  206.     short row, col, i, n;
  207.  
  208.     if (cur_level < max_level) {
  209.         return;
  210.     }
  211.  
  212.     if (monster->m_flags & STEALS_GOLD) {
  213.         obj = alloc_object();
  214.         obj->what_is = GOLD;
  215.         obj->quantity = get_rand((cur_level * 15), (cur_level * 30));
  216.     } else {
  217.         if (!rand_percent((int) monster->drop_percent)) {
  218.             return;
  219.         }
  220.         obj = gr_object();
  221.     }
  222.     row = monster->row;
  223.     col = monster->col;
  224.  
  225.     for (n = 0; n <= 5; n++) {
  226.         for (i = -n; i <= n; i++) {
  227.             if (try_to_cough(row+n, col+i, obj)) {
  228.                 return;
  229.             }
  230.             if (try_to_cough(row-n, col+i, obj)) {
  231.                 return;
  232.             }
  233.         }
  234.         for (i = -n; i <= n; i++) {
  235.             if (try_to_cough(row+i, col-n, obj)) {
  236.                 return;
  237.             }
  238.             if (try_to_cough(row+i, col+n, obj)) {
  239.                 return;
  240.             }
  241.         }
  242.     }
  243.     free_object(obj);
  244. }
  245.  
  246. try_to_cough(row, col, obj)
  247. short row, col;
  248. object *obj;
  249. {
  250.     if ((row < MIN_ROW) || (row > (DROWS-2)) || (col < 0) || (col>(DCOLS-1))) {
  251.         return(0);
  252.     }
  253.     if ((!(dungeon[row][col] & (OBJECT | STAIRS | TRAP))) &&
  254.         (dungeon[row][col] & (TUNNEL | FLOOR | DOOR))) {
  255.         place_at(obj, row, col);
  256.         if (((row != rogue.row) || (col != rogue.col)) &&
  257.             (!(dungeon[row][col] & MONSTER))) {
  258.             mvaddch(row, col, get_dungeon_char(row, col));
  259.         }
  260.         return(1);
  261.     }
  262.     return(0);
  263. }
  264.  
  265. seek_gold(monster)
  266. object *monster;
  267. {
  268.     short i, j, rn, s;
  269.  
  270.     if ((rn = get_room_number(monster->row, monster->col)) < 0) {
  271.         return(0);
  272.     }
  273.     for (i = rooms[rn].top_row+1; i < rooms[rn].bottom_row; i++) {
  274.         for (j = rooms[rn].left_col+1; j < rooms[rn].right_col; j++) {
  275.             if ((gold_at(i, j)) && !(dungeon[i][j] & MONSTER)) {
  276.                 monster->m_flags |= CAN_FLIT;
  277.                 s = mon_can_go(monster, i, j);
  278.                 monster->m_flags &= (~CAN_FLIT);
  279.                 if (s) {
  280.                     move_mon_to(monster, i, j);
  281.                     monster->m_flags |= ASLEEP;
  282.                     monster->m_flags &= (~(WAKENS | SEEKS_GOLD));
  283.                     return(1);
  284.                 }
  285.                 monster->m_flags &= (~SEEKS_GOLD);
  286.                 monster->m_flags |= CAN_FLIT;
  287.                 mv_monster(monster, i, j);
  288.                 monster->m_flags &= (~CAN_FLIT);
  289.                 monster->m_flags |= SEEKS_GOLD;
  290.                 return(1);
  291.             }
  292.         }
  293.     }
  294.     return(0);
  295. }
  296.  
  297. gold_at(row, col)
  298. short row, col;
  299. {
  300.     if (dungeon[row][col] & OBJECT) {
  301.         object *obj;
  302.  
  303.         if ((obj = object_at(&level_objects, row, col)) &&
  304.                 (obj->what_is == GOLD)) {
  305.             return(1);
  306.         }
  307.     }
  308.     return(0);
  309. }
  310.  
  311. check_gold_seeker(monster)
  312. object *monster;
  313. {
  314.     monster->m_flags &= (~SEEKS_GOLD);
  315. }
  316.  
  317. check_imitator(monster)
  318. object *monster;
  319. {
  320.     char msg[80];
  321.  
  322.     if (monster->m_flags & IMITATES) {
  323.         wake_up(monster);
  324.         if (!blind) {
  325.             mvaddch(monster->row, monster->col,
  326.                     get_dungeon_char(monster->row, monster->col));
  327.             check_message();
  328.             sprintf(msg, "wait, that's a %s!", mon_name(monster));
  329.             message(msg, 1);
  330.         }
  331.         return(1);
  332.     }
  333.     return(0);
  334. }
  335.  
  336. imitating(row, col)
  337. register short row, col;
  338. {
  339.     if (dungeon[row][col] & MONSTER) {
  340.         object *object_at(), *monster;
  341.  
  342.         if (monster = object_at(&level_monsters, row, col)) {
  343.             if (monster->m_flags & IMITATES) {
  344.                 return(1);
  345.             }
  346.         }
  347.     }
  348.     return(0);
  349. }
  350.  
  351. sting(monster)
  352. object *monster;
  353. {
  354.     short sting_chance = 35;
  355.     char msg[80];
  356.  
  357.     if ((rogue.str_current <= 3) || sustain_strength) {
  358.         return;
  359.     }
  360.     sting_chance += (6 * (6 - get_armor_class(rogue.armor)));
  361.  
  362.     if ((rogue.exp + ring_exp) > 8) {
  363.         sting_chance -= (6 * ((rogue.exp + ring_exp) - 8));
  364.     }
  365.     if (rand_percent(sting_chance)) {
  366.         sprintf(msg, "the %s's bite has weakened you",
  367.         mon_name(monster));
  368.         message(msg, 0);
  369.         rogue.str_current--;
  370.         print_stats(STAT_STRENGTH);
  371.     }
  372. }
  373.  
  374. drop_level()
  375. {
  376.     int hp;
  377.  
  378.     if (rand_percent(80) || (rogue.exp <= 5)) {
  379.         return;
  380.     }
  381.     rogue.exp_points = level_points[rogue.exp-2] - get_rand(9, 29);
  382.     rogue.exp -= 2;
  383.     hp = hp_raise();
  384.     if ((rogue.hp_current -= hp) <= 0) {
  385.         rogue.hp_current = 1;
  386.     }
  387.     if ((rogue.hp_max -= hp) <= 0) {
  388.         rogue.hp_max = 1;
  389.     }
  390.     add_exp(1, 0);
  391. }
  392.  
  393. drain_life()
  394. {
  395.     short n;
  396.  
  397.     if (rand_percent(60) || (rogue.hp_max <= 30) || (rogue.hp_current < 10)) {
  398.         return;
  399.     }
  400.     n = get_rand(1, 3);        /* 1 Hp, 2 Str, 3 both */
  401.  
  402.     if ((n != 2) || (!sustain_strength)) {
  403.         message("you feel weaker", 0);
  404.     }
  405.     if (n != 2) {
  406.         rogue.hp_max--;
  407.         rogue.hp_current--;
  408.         less_hp++;
  409.     }
  410.     if (n != 1) {
  411.         if ((rogue.str_current > 3) && (!sustain_strength)) {
  412.             rogue.str_current--;
  413.             if (coin_toss()) {
  414.                 rogue.str_max--;
  415.             }
  416.         }
  417.     }
  418.     print_stats((STAT_STRENGTH | STAT_HP));
  419. }
  420.  
  421. m_confuse(monster)
  422. object *monster;
  423. {
  424.     char msg[80];
  425.  
  426.     if (!rogue_can_see(monster->row, monster->col)) {
  427.         return(0);
  428.     }
  429.     if (rand_percent(45)) {
  430.         monster->m_flags &= (~CONFUSES);    /* will not confuse the rogue */
  431.         return(0);
  432.     }
  433.     if (rand_percent(55)) {
  434.         monster->m_flags &= (~CONFUSES);
  435.         sprintf(msg, "the gaze of the %s has confused you", mon_name(monster));
  436.         message(msg, 1);
  437.         confuse();
  438.         return(1);
  439.     }
  440.     return(0);
  441. }
  442.  
  443. flame_broil(monster)
  444. object *monster;
  445. {
  446.     short row, col;
  447.  
  448.     if ((!mon_sees(monster, rogue.row, rogue.col)) || coin_toss()) {
  449.         return(0);
  450.     }
  451.     row = rogue.row - monster->row;
  452.     col = rogue.col - monster->col;
  453.     if (row < 0) {
  454.         row = -row;
  455.     }
  456.     if (col < 0) {
  457.         col = -col;
  458.     }
  459.     if (((row != 0) && (col != 0) && (row != col)) ||
  460.         ((row > 7) || (col > 7))) {
  461.         return(0);
  462.     }
  463.     if ((!blind) && (!rogue_is_around(monster->row, monster->col))) {
  464.         row = monster->row;
  465.         col = monster->col;
  466.         get_closer(&row, &col, rogue.row, rogue.col);
  467.         standout();
  468.         do {
  469.             mvaddch(row, col, '~');
  470.             refresh();
  471.             get_closer(&row, &col, rogue.row, rogue.col);
  472.         } while ((row != rogue.row) || (col != rogue.col));
  473.         standend();
  474.         row = monster->row; col = monster->col;
  475.         get_closer(&row, &col, rogue.row, rogue.col);
  476.         do {
  477.             mvaddch(row, col, get_dungeon_char(row, col));
  478.             refresh();
  479.             get_closer(&row, &col, rogue.row, rogue.col);
  480.         } while ((row != rogue.row) || (col != rogue.col));
  481.     }
  482.     mon_hit(monster, flame_name, 1);
  483.     return(1);
  484. }
  485.  
  486. get_closer(row, col, trow, tcol)
  487. short *row, *col;
  488. short trow, tcol;
  489. {
  490.     if (*row < trow) {
  491.         (*row)++;
  492.     } else if (*row > trow) {
  493.         (*row)--;
  494.     }
  495.     if (*col < tcol) {
  496.         (*col)++;
  497.     } else if (*col > tcol) {
  498.         (*col)--;
  499.     }
  500. }
  501.